use std::thread::sleep;
use std::time::Duration;
use std::{
    sync::{mpsc, Arc, Mutex},
    thread,
};

type Job = Box<dyn FnOnce() + Send + 'static>;

pub struct ThreadPool {
    // 线程池的实现代码
    sender: Option<mpsc::Sender<Job>>,
    pool: Vec<Option<thread::JoinHandle<()>>>,
}

impl ThreadPool {
    pub fn new(size: usize) -> ThreadPool {
        assert!(size > 0);

        let (sender, receiver) = mpsc::channel::<Job>();

        let mut pool = Vec::with_capacity(size);
        //  套上Arc和mutex，其中arc的clone用于进程间传递，mutex用于进程间互斥
        let mut receiver = Arc::new(Mutex::new(receiver));

        for _ in 1..10 {
            let receiver = receiver.clone();
            //主动清理loop循环，而不是被动等程序停止来关闭
            let handle = thread::spawn(move || loop {
                let message = receiver.lock().unwrap().recv();
                match message {
                    Ok(job) => {
                        println!("Worker got a job; executing.");
                        job();
                    }
                    Err(_) => {
                        println!("Worker disconnected; shutting down.");
                        break;
                    }
                }
            });
            //创建线程池
            pool.push(Some(handle));
        }

        ThreadPool {
            sender: Some(sender),
            pool: pool,
        }
    }

    pub fn execute<F>(&self, f: F)
    where
        F: FnOnce() + Send + 'static,
    {
        let job = Box::new(f);
        self.sender.as_ref().unwrap().send(job).unwrap();
    }
}
